package cn.itsource.pethome.system.atools.verificationCode.controller;

import cn.itsource.pethome.constants.BaseConstants;
import cn.itsource.pethome.system.atools.verificationCode.domain.PhoneCode;
import cn.itsource.pethome.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * @Author:R
 * @Date:2023/1/10 17:35
 * Description
 */
@RestController
@RequestMapping("/vcode")
@Api(description="获取验证码")
public class VCodeController {
    @Autowired
    private RedisTemplate redisTemplate;

    @GetMapping("/{key}")
    @ApiOperation(value = "发送图形验证码给前端")
    public AjaxResult getVCode(@PathVariable String key){
        try {
            //生成图形验证码，返回base64形式给前端
            String code = StrUtils.getRandomString(4).toLowerCase();
            String encode = VerifyCodeUtils.VerifyCode(115, 40, code);
            //存入reids
            redisTemplate.opsForValue().set(key,code,5, TimeUnit.MINUTES);
            return AjaxResult.success().setData(encode);
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("图片验证码生成失败");
            return AjaxResult.error().setMsg("网络异常，请联系管理员");
        }
    }

    @PostMapping
    @ApiOperation(value = "发送手机短信验证码给用户，注册用")
    public AjaxResult sendPhoneMsg(@RequestBody PhoneCode phoneCode){
        String phone = phoneCode.getPhone();
        String imageCode = phoneCode.getImageCode();
        String imageCodeKey = phoneCode.getImageCodeKey();
        //数据校验  防止非法访问
        if (imageCodeKey == null || "".equals(imageCodeKey.trim()))
            return AjaxResult.error().setMsg("非法访问！");
        if (imageCode == null || "".equals(imageCode.trim()))
            return AjaxResult.error().setMsg("图形验证码不能为空！");
        if (phone == null || "".equals(phone.trim()))
            return AjaxResult.error().setMsg("手机号不能为空！");
        if(phone.length() != 11)
            return AjaxResult.error().setMsg("手机号应为11位！");
        if(!MobileUtil.checkPhone(phone))
            return AjaxResult.error().setMsg("手机号错误或者非大陆手机号");
        //图形验证码校验
        String value = (String)redisTemplate.opsForValue().get(imageCodeKey);
        if (value == null)
            return AjaxResult.error().setMsg("图形验证码已过期，请重新获取！");
        if(!value.equals(imageCode.trim()))
            return AjaxResult.error().setMsg("图形验证码输入错误！");

        return sendmsg(phone,BaseConstants.Phone.PHONE_KEY_SUFFIX,BaseConstants.Phone.PHONETIME_KEY_SUFFIX,BaseConstants.Phone.VCODE_TIMEOUT);
    }

    //发送短信验证码
    private AjaxResult sendmsg(String phone,String businessKey,String businessKeyTime,long businessKeyTimeOut) {
        //防止频繁获取手机验证码===>将时间戳存入redis
        String randomCode = StrUtils.getRandomString(4);        //生成随机手机号验证码
        //先去获取上次存入的时间戳，如果有，就判断是否超过60秒，没有就生成
        String firstTimeKey = phone + businessKeyTime;   //存时间的key
        String phoneKey = phone + businessKey;           //存手机号验证码的key
        Long lastTime = (Long)redisTemplate.opsForValue().get(firstTimeKey);
        if (lastTime != null){
            long nowTime = System.currentTimeMillis();
            if (nowTime - lastTime < 60000){    //间隔时间小于60s
                return AjaxResult.error().setMsg("请勿频繁获取验证码！");
            }else {  //间隔时间大于60s  仍然发送上一次的验证码
                randomCode = (String) redisTemplate.opsForValue().get(phoneKey);
                savePhoneVcodeAndTime(firstTimeKey,phoneKey,randomCode,businessKeyTimeOut);
            }
        }else {
            //第一次进来，就正常存时间，验证码
            savePhoneVcodeAndTime(firstTimeKey,phoneKey,randomCode,businessKeyTimeOut);
        }
        //发送手机验证码
//        MassageUtil.sendMsg(phone,randomCode);
        System.out.println(phone+"---"+randomCode);
        return AjaxResult.success();
    }

    @PostMapping("/phoneCode")
    @ApiOperation(value = "发送手机短信验证码给用户，绑定用")
    public AjaxResult sendPhoneMsgBind(@RequestBody PhoneCode phoneCode){
        String phone = phoneCode.getPhone();
        //数据校验  防止非法访问
        if (phone == null || "".equals(phone.trim()))
            return AjaxResult.error().setMsg("手机号不能为空！");
        if(phone.length() != 11)
            return AjaxResult.error().setMsg("手机号应为11位！");
        if(!MobileUtil.checkPhone(phone))
            return AjaxResult.error().setMsg("手机号错误或者非大陆手机号");
        return sendmsg(phone,BaseConstants.Phone.PHONE_KEY_BIND,BaseConstants.Phone.PHONETIME_KEY_BIND,BaseConstants.Phone.VCODE_BIND_TIMEOUT);
    }

    //保存手机号验证码过期时间
    private void savePhoneVcodeAndTime(String firstTimeKey,String phoneKey,String randomCode,long businessKeyTimeOut){
        //第一次进来，就正常存时间，验证码
        long timeMillis = System.currentTimeMillis();
        //存时间戳
        redisTemplate.opsForValue().set(firstTimeKey,timeMillis, businessKeyTimeOut,TimeUnit.MINUTES);
        redisTemplate.opsForValue().set(phoneKey,randomCode,businessKeyTimeOut,TimeUnit.MINUTES);
    }
}
